﻿using System;
using K9Nano.Application.Features;
using K9Nano.Configuration.Startup;
using K9Nano.Dependency;
using K9Nano.Events;
using K9Nano.Runtime;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class StartupExtensions
    {
        public static IK9NanoAppBuilder AddK9NanoCore(this IServiceCollection services)
        {
            return AddK9NanoCore(services, null);
        }

        public static IK9NanoAppBuilder AddK9NanoCore(this IServiceCollection services,
            Action<StartupConfiguration> builder)
        {
            var config = StartupConfiguration.Global;
            builder?.Invoke(config);

            services.AddSingleton(config.ApiInfo);
            services.AddSingleton(config.MultiTenancyConfig);
            services.AddSingleton(config.SettingDefinitionManager);
            services.AddTransient(typeof(IAmbientScopeProvider<>), typeof(DataContextAmbientScopeProvider<>));
            services.RegisterConventionalAssembly(typeof(StartupExtensions).Assembly);

            services.AddSingleton<IIocHelper>(new DefaultIocHelper(services));

            services.AddTransient(typeof(Lazy<>), typeof(LazyLoader<>));

            /* LB */
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders =
                    ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;

                options.KnownProxies.Clear();

                options.KnownNetworks.Clear();
            });
            var appBuilder = new K9NanoAppBuilder(services);
            return appBuilder;
        }

        public static IApplicationBuilder UseK9NanoCore(this IApplicationBuilder app)
        {
            app.UseForwardedHeaders();

            // Initialize FeatureManager
            var featureManager = app.ApplicationServices.GetService<IFeatureManager>();
            if (featureManager is FeatureManager manager)
            {
                manager.Initialize();
            }

            using var scope = app.ApplicationServices.CreateScope();

            // Initialize EventHandlers
            scope.ServiceProvider.GetService<IEventHandlerConventionRegister>().RegisterHandlers();

            return app;
        }
    }
}